using HtERP.Data;
using Newtonsoft.Json;


namespace HtERP.Services;

/// <summary>
/// 配置服务实现
/// </summary>
public class ConfigService : IConfigService
{
    private readonly IConfiguration _configuration;
    private readonly ILogger<ConfigService> _logger;
    private readonly string _appSettingsPath;
    private readonly object _fileLock = new object();

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="configuration">配置对象</param>
    /// <param name="logger">日志记录器</param>
    /// <param name="env">环境变量</param>
    public ConfigService(IConfiguration configuration, ILogger<ConfigService> logger, IWebHostEnvironment env)
    {
        _configuration = configuration;
        _logger = logger;
        _appSettingsPath = Path.Combine(env.ContentRootPath, "appsettings.json");
    }

    /// <inheritdoc />
    public T? GetConfig<T>(string sectionName)
    {
        try
        {
            _logger.LogInformation("获取配置: {SectionName}", sectionName);
            return _configuration.GetSection(sectionName).Get<T?>();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取配置失败: {SectionName}", sectionName);
            return default;
        }
    }

    /// <inheritdoc />
    public async Task<bool> UpdateConfigAsync<T>(string sectionName, T config)
    {
        try
        {
            _logger.LogInformation("更新配置: {SectionName}", sectionName);

            // 1. 检查文件是否存在
            if (!File.Exists(_appSettingsPath))
            {
                _logger.LogWarning("配置文件不存在: {Path}", _appSettingsPath);
                return false;
            }

            // 2. 读取当前配置文件
            string jsonContent;
            try
            {
                lock (_fileLock)
                {
                    jsonContent = File.ReadAllText(_appSettingsPath);
                }
            }
            catch (IOException ioEx)
            {
                _logger.LogError(ioEx, "读取配置文件失败: {Path}. 可能是文件被锁定或权限不足.", _appSettingsPath);
                return false;
            }

            // 3. 解析配置文件
            Dictionary<string, object> configObject;
            try
            {
                configObject = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonContent);
                if (configObject == null)
                {
                    configObject = new Dictionary<string, object>();
                }
            }
            catch (JsonException jsonEx)
            {
                _logger.LogError(jsonEx, "解析配置文件失败: {Path}", _appSettingsPath);
                return false;
            }

            // 4. 更新指定节的配置
            try
            {
                var configJson = JsonConvert.SerializeObject(config);
                var configDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(configJson);
                if (configDict == null)
                {
                    configDict = new Dictionary<string, object>();
                }
                configObject[sectionName] = configDict;
            }
            catch (JsonException jsonEx)
            {
                _logger.LogError(jsonEx, "序列化配置对象失败: {SectionName}", sectionName);
                return false;
            }

            // 5. 写回配置文件
            try
            {
                var updatedJson = JsonConvert.SerializeObject(configObject, Formatting.Indented);
                lock (_fileLock)
                {
                    // 确保目录存在
                    string directory = Path.GetDirectoryName(_appSettingsPath);
                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }
                    
                    File.WriteAllText(_appSettingsPath, updatedJson);
                }
            }
            catch (IOException ioEx)
            {
                _logger.LogError(ioEx, "写入配置文件失败: {Path}. 可能是文件被锁定或权限不足.", _appSettingsPath);
                // 尝试使用用户配置目录作为备选
                try
                {
                    string userConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DbBackupGUI", "settings.json");
                    string userConfigDir = Path.GetDirectoryName(userConfigPath);
                    if (!Directory.Exists(userConfigDir))
                    {
                        Directory.CreateDirectory(userConfigDir);
                    }
                    
                    var updatedJson = JsonConvert.SerializeObject(configObject, Formatting.Indented);
                    File.WriteAllText(userConfigPath, updatedJson);
                    _logger.LogInformation("配置已保存到用户目录: {Path}", userConfigPath);
                    return true;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "保存配置到用户目录也失败");
                    return false;
                }
            }

            _logger.LogInformation("配置更新成功: {SectionName}", sectionName);
            return true;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "配置更新失败: {SectionName}", sectionName);
            return false;
        }
    }

    /// <inheritdoc />
    public string GetDefaultBackupPath()
    {
        try
        {
            var path = _configuration.GetValue<string>("BackupSettings:DefaultBackupPath");
            if (string.IsNullOrEmpty(path))
            {
                return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "DatabaseBackups");
            }

            // 处理环境变量
            return Environment.ExpandEnvironmentVariables(path);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取默认备份路径失败");
            return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "DatabaseBackups");
        }
    }

    /// <inheritdoc />
    public async Task<bool> SetDefaultBackupPathAsync(string path)
    {
        try
        {
            _logger.LogInformation("设置默认备份路径: {Path}", path);

            // 确保路径存在
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            // 更新备份设置
            var backupSettings = _configuration.GetSection("BackupSettings").Get<BackupSettings>();
            if (backupSettings == null)
            {
                backupSettings = new BackupSettings();
            }
            
            backupSettings.DefaultBackupPath = path;
            return await UpdateConfigAsync("BackupSettings", backupSettings);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "设置默认备份路径失败: {Path}", path);
            return false;
        }
    }

    /// <inheritdoc />
    public int GetDefaultRetentionCount()
    {
        try
        {
            return _configuration.GetValue<int>("BackupSettings:DefaultRetentionCount", 7);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取默认保留数量失败");
            return 7;
        }
    }

    /// <inheritdoc />
    public async Task<bool> SetDefaultRetentionCountAsync(int count)
    {
        try
        {
            if (count < 1)
            {
                _logger.LogWarning("保留数量不能小于1");
                return false;
            }

            _logger.LogInformation("设置默认保留数量: {Count}", count);

            // 更新备份设置
            var backupSettings = _configuration.GetSection("BackupSettings").Get<BackupSettings>();
            if (backupSettings == null)
            {
                backupSettings = new BackupSettings();
            }
            
            backupSettings.DefaultRetentionCount = count;
            return await UpdateConfigAsync("BackupSettings", backupSettings);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "设置默认保留数量失败: {Count}", count);
            return false;
        }
    }
}